/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                                                                           *
 *                          Copyright (c) 2010                               *
 *                  Alen Stojanov [ ioi.alen@gmail.com ]                     *
 *                Jacobs University Bremen, Bremen, Germany                  *
 *                                                                           *
 *                          All Rights Reserved.                             *
 *                                                                           *
 *    Permission to use, copy, modify and distribute this software and       *
 *    its documentation is hereby granted, provided that both the            *
 *    copyright notice and this permission notice appear in all copies of    *
 *    the software, derivative works or modified versions, and any           *
 *    portions thereof, and that both notices appear in supporting           *
 *    documentation.                                                         *
 *                                                                           *
 *    This code is distributed in the hope that it will be useful, but       *
 *    WITHOUT ANY WARRANTY; without even the implied warranty of             *
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS       *
 *    DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER          *
 *    RESULTING FROM THE USE OF THIS SOFTWARE.                               *
 *                                                                           *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifndef GLPREVIEW_H_
#define GLPREVIEW_H_

#include <QGLWidget>
#include <QMutex>

#include "tsdata.h"

#define PREVIEW_PIXMAP_COUNT 4

class GLPreview : public QGLWidget
{
	Q_OBJECT

public:
	/**
	 * Default constructor
	 */
	GLPreview(QWidget *parent = 0);
	/**
	 * @brief Remove the particular TS of the preview graph
	 * @param data Pointer to the TS data being removed
	 */
	void removeSeries(TSData *data);

public slots:
/**
	 * @brief Add a particular TS to the preview graph
	 *
	 * This function will include the data into the graph, and will
	 * repaint the graph such that the new TS is included
	 *
	 * @param data Pointer to the new TS data being added
	 */
	void on_addSeries(QVector<TSData*> data);

	void on_rangePercent_change(double percent);

protected:
	/**
	 * @brief Overloaded method to initialize the OpenGL widget
	 */
	void initializeGL();
	/**
	 * @brief Overloaded method to repaint the OpenGL widget
	 */
	void paintGL();
	/**
	 * @brief Overloaded method to resize the OpenGL widget
	 * @param width 	The width of the viewport
	 * @param height 	The height of the viewort
	 */
	void resizeGL(int width, int height);
	/**
	 * @brief repaint the preview scence
	 */
	void repaintPreview ();
	/**
	 * @brief Overload the Mouse press event to detect the last mouse position
	 * @param event 	The default mouse event
	 */
	void mousePressEvent(QMouseEvent *event);
	/**
	 * @brief Overload the Mouse move event to recaluclate the range of the preview
	 * @param event		The default mouse event
	 */
	void mouseMoveEvent(QMouseEvent *event);

signals:
	/**
	 * @brief Uppon each range change, create a signal which will signal the other widgets the new range
	 * @param rangeMinX		The new minimal x-axis range of the time series
	 * @param rangeMaxX		The new maximum x-axis range of the time series
	 */
	void rangeChanged(double rangeMinX, double rangeMaxX);

private:
	/**
	 * @brief Use a mutex for concurency
	 *
	 * Ensure that when the data is being updated, repaint on the scene has not been
	 * performed (this process might take a long time in certain situations)
	 */
	QMutex mutex;
	/**
	 * Pixmap used as a rendered texture on the preview graph. Works as mipmap, such
	 * that 4 pixmaps are created each with ratios: 0.25, 0.5, 0.75, 1.0
	 */
	QPixmap pixmap[PREVIEW_PIXMAP_COUNT];
	/**
	 * If repaintTextureMode is set to true then the preview graph will be repainted,
	 * otherwise the rendered texture will be shown in the graph
	 */
	bool repaintTextureMode;
	/**
	 * Defines the ratios for the repaintTextureMode
	 */
	double repaintTextureModeRatio;
	/**
	 * The width of the texture intially rendered
	 */
	double repaintTextureWidth;
	/**
	 * Define the range of the preview - minumum of the x-axis
	 */
	double rangeMinX;
	/**
	 * Define the range of the preview - maximum of the x-axis
	 */
	double rangeMaxX;
	/**
	 * Define the range of the preview that maps to the texutre - minumum of the x-axis
	 */
	double mappedRangeMinX;
	/**
	 * Define the range of the preview - that maps to the texutre maximum of the x-axis
	 */
	double mappedRangeMaxX;
	/**
	 * Grab the last position of the mouse on a press event
	 */
	QPoint lastPos;
	/**
	 * The dimensions of the preview widget before the last change
	 */
	QSize lastSize;
	/**
	 * @brief Store all the data into one single vector of TSData
	 */
	QVector<TSData*> data;
	/**
	 * @brief Number of grid lines on the X-axis
	 */
	int gridSizeX;
	/**
	 * @brief Number of grid lines on the Y-axis
	 */
	int gridSizeY;
	/**
	 * @brief Maximal X coordinate of the viewport
	 */
	double maxX;
	/**
	 * @brief Minimal X coordinate of the viewport
	 */
	double minX;
	/**
	 * @brief Maximal Y coordinate of the viewport
	 */
	double maxY;
	/**
	 * @brief Minimal Y coordinate of the viewport
	 */
	double minY;
	/**
	 * @brief Ensure that when a new series has been added, a new color is used for that TS
	 */
	QColor getColorByIndex(int index);
	/**
	 * @brief Repaints the texture for preview graph
	 */
	void repaintTexture(double ratio);
	/**
	 * @brief Default constructor
	 */
	~GLPreview();
};

#endif /* GLSINGLEPREVIEW_H_ */
